/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ai;

import java.util.LinkedList;

/**
 *
 * @author root
 */
public class SemanticExp {
    public static final int CONST = 0;
    public static final int LABEL = 1;
    public static final int LABELCONV = 2;
    public static final int PARAM = 3;
    public static final int FUNC = 4;
    public static final int SEMEXP = 5;
    
    public SemanticExp(String pName, int pType) throws ParseException{
        mName = pName;
        mType = pType;
        mParamIndex = -1;
        mParamGroup = false;
        if(mType < 0 || mType > 5){
            throw new ParseException("pType = " + pType + " is out of range!");
        }
        mIn = new LinkedList<Input>();
        mOut = new LinkedList<SemanticExp>();
    }

    public SemanticExp halfClone(){
        try {
            SemanticExp lSemExp = new SemanticExp(mName, mType);
            lSemExp.mParamIndex = mParamIndex;
            lSemExp.mParamGroup = mParamGroup;
            lSemExp.mIn = mIn;
            lSemExp.mOut = new LinkedList<SemanticExp>();
            return lSemExp;
        } catch (ParseException ex) {
        }
        
        // Will never happen.
        return null;
    }
    
    public void addInput(String pParam, boolean pGroup){
        mIn.add(new Input(pParam, pGroup));
    }
    public void addOperation(SemanticExp pOE){
        mOut.add(pOE);
    }
    public int getType(){
        return mType;
    }
    public String getName(){
        return mName;
    }
    public void setName(String pName){
        mName = pName;
    }
    public int getParamIndex(){
        return mParamIndex;
    } 
    public void setParamIndex(int pIndex){
        mParamIndex = pIndex;
    }
    public boolean getParamGroup(){
        return mParamGroup;
    }
    public void setParamGroup(boolean pParamGroup){
        mParamGroup = pParamGroup;
    }
    public String getSecondLabel(){
        return mSecondLabel;
    }
    public void setSecondLabel(String pLabel){
        mSecondLabel = pLabel;
    }
    
    public LinkedList<Input> getInputs(){
        return mIn;
    }
    public LinkedList<SemanticExp> getOutputs(){
        return mOut;
    }
    
    public String toString(){
        if(mType == CONST || mType == LABEL || mType == PARAM){
            return mName;
        }
        else if(mType == LABELCONV){
            return mName + ":" + mSecondLabel;
        }
        else if(mType == FUNC){
            String lStr = mName;
            
            if(!mOut.isEmpty()){
                lStr += "(";
            }
            
            for(SemanticExp se : mOut){
                if(se != mOut.getLast()){
                    lStr += se.toString() + ", ";
                }
                else{
                    lStr += se.toString() + ")";
                }
            }
            return lStr;
            
        }
        else if(mType == SEMEXP){
            String lStr = "<";
            if(!mIn.isEmpty()){
                lStr += "\\";
            }
            for(Input i : mIn){
                if(!i.equals(mIn.getLast())){
                    lStr += i + ".";
                }
                else{
                    lStr += i + " ";
                }
            }
            for(SemanticExp se : mOut){
                if(se != mOut.getLast()){
                    lStr += se.toString() + ", ";
                }
                else{
                    lStr += se.toString();
                }
            }
            return lStr + ">";
        }
        return "";
    }
    
    public class Input{
        public Input(String pName, boolean pGroup){
            mName = pName;
            mGroup = pGroup;
        }
        
        public boolean equals(Object o){
            if(!(o instanceof Input)){
                return false;
            }
            return mName.equals(((Input)o).mName) && mGroup == ((Input)o).mGroup;
        }
        
        public String toString(){
            String lStr = mName;
            if(mGroup){
                lStr += "+";
            }
            return lStr;
        }
        
        public String mName;
        public boolean mGroup;
    }

    private String mName;
    private String mSecondLabel;
    private int mType;
    private LinkedList<Input> mIn;
    private LinkedList<SemanticExp> mOut;
    private int mParamIndex;
    private boolean mParamGroup;
}
